﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusinessEntities;
using DataAccessLayer;
using Draco.Algorithms;
using Draco.DataStructure;

namespace BusinessLayer
{
    public class SupermarketBLL:LocatingPointBLL<Supermarket>
    {
        private D_LinkList<Supermarket> supermarkets;

        public D_LinkList<Supermarket> Supermarkets { get { return supermarkets; } }

        public SupermarketBLL()
        {
            SupermarketDAL dal = new SupermarketDAL();
            supermarkets = dal.GetElements();
        }


        #region 查找附近超市

        /// <summary>
        /// 查找指定坐标附近的超市
        /// </summary>
        /// <param name="x">坐标x</param>
        /// <param name="y">坐标y</param>
        /// <param name="errorLevel">允许误差范围</param>
        /// <returns>超市列表</returns>
        public override D_LinkList<Supermarket> GetNearbySites(int x, int y, SeekAdmissibleError errorLevel)
        {
            int hashLen = 8;
            switch (errorLevel)
            {
                case SeekAdmissibleError.Level_1:
                    hashLen = 8;
                    break;
                case SeekAdmissibleError.Level_2:
                    hashLen = 7;
                    break;
                case SeekAdmissibleError.Level_3:
                    hashLen = 6;
                    break;
                case SeekAdmissibleError.Level_4:
                    hashLen = 5;
                    break;
                case SeekAdmissibleError.Level_5:
                    hashLen = 4;
                    break;
                case SeekAdmissibleError.Level_6:
                    hashLen = 3;
                    break;
                case SeekAdmissibleError.Level_7:
                    hashLen = 2;
                    break;
                case SeekAdmissibleError.Level_8:
                    hashLen = 1;
                    break;
            }
            D_GeoHash geo = new D_GeoHash(x, y);
            geo.SetHashLenght(hashLen);
            return GetNearbySupermarkets(geo.GetGeoHashBase4For9());
        }

        private D_LinkList<Supermarket> GetNearbySupermarkets(string geohash)
        {
            D_LinkList<Supermarket> nearby = new D_LinkList<Supermarket>();
            foreach (Supermarket supermarket in Supermarkets)
            {
                if (D_String.PrefixMatching(supermarket.GeoHash, geohash))
                {
                    nearby.Add(supermarket);
                }
            }
            return nearby;
        }

        private D_LinkList<Supermarket> GetNearbySupermarkets(D_LinkList<string> geohashs)
        {
            D_LinkList<Supermarket> nearby = new D_LinkList<Supermarket>();
            foreach (Supermarket supermarket in Supermarkets)
            {
                foreach (string geohash in geohashs)
                {
                    if (D_String.PrefixMatching(supermarket.GeoHash, geohash))
                    {
                        nearby.Add(supermarket);
                    }
                }
            }
            return nearby;
        }

        #endregion

        public override Supermarket GetSite(int id)
        {
            foreach (Supermarket supermarket in Supermarkets)
            {
                if (supermarket.ID == id)
                {
                    return supermarket;
                }
            }
            return null;
        }

        public override void AddSite(Supermarket site)
        {
            //id从数据库获得
            SupermarketDAL dal = new SupermarketDAL();
            dal.Insert(site.Name, site.X, site.Y, site.Grade);
            int id = dal.GetLastInsertID();

            Supermarket temp = new Supermarket(id, site.Name, site.X, site.Y, site.Grade);
            Supermarkets.Add(temp);
        }

        public override void UpdateSite(Supermarket site)
        {
            for (int i = 0; i < Supermarkets.Count; i++)
            {
                if (Supermarkets[i].ID == site.ID)
                {
                    Supermarkets[i] = site;
                }
            }
            //更新数据库
            SupermarketDAL dal = new SupermarketDAL();
            dal.Update(site.ID, site.Name, site.X, site.Y, site.Grade);
        }

        public override void DeleteSite(int id)
        {
            int[] array = new int[Supermarkets.Count];
            for (int i = 0; i < Supermarkets.Count; i++)
            {
                array[i] = Supermarkets[i].ID;
            }

            int index = D_Search.BinarySearchIndex(array, id);

            Supermarkets.RemoveAt(index);

            //更新数据库
            SupermarketDAL dal = new SupermarketDAL();
            dal.Delete(id);
        }
    }

}
